/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.diplomka.servicelayer.xmlconvertors;

import cz.fi.muni.diplomka.common.Coordinates;
import cz.fi.muni.diplomka.common.enumeration.BuildingType;
import cz.fi.muni.diplomka.common.enumeration.ResourceType;
import cz.fi.muni.diplomka.common.enumeration.UnitType;
import cz.muni.fi.diplomka.servicelayer.dto.BuildingInCity;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Class used for getting various limit info from XML
 *
 * @author Jakub Kutil
 */
public class LimitsConvertor {

    private LocationString locationString = new LocationString();
     /**
     * Gets info what Resources should be in newly created City from XML
     *
     * @return map of Resources of new City
     */
    public Map<String, Integer> getStartingResourcesFromXML() {

        Map<String, Integer> startingResources = new HashMap<>();

        try {

            File fXmlFile = new File(locationString.getXMLLocation() + "\\limits.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = "/limits/startingResources/resources";
            Node node = (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

            Element element = (Element) node;

            for (ResourceType resourceType : ResourceType.values()) {
                startingResources.put(resourceType.name(), Integer.parseInt(element.getElementsByTagName(resourceType.name()).item(0).getTextContent()));
                System.out.println(resourceType.name() + Integer.parseInt(element.getElementsByTagName(resourceType.name()).item(0).getTextContent()));
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return startingResources;
    }

     /**
     * Gets info what Units should be in newly created City from XML
     *
     * @return list of Units of new City
     */
    public Map<String, Integer> getStartingUnitsFromXML() {

        Map<String, Integer> startingResources = new HashMap<>();

        try {

            File fXmlFile = new File(locationString.getXMLLocation() + "\\limits.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = "/limits/startingResources/units";
            Node node = (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

            Element element = (Element) node;

            for (UnitType unitType : UnitType.values()) {
                startingResources.put(unitType.name(), Integer.parseInt(element.getElementsByTagName(unitType.name()).item(0).getTextContent()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return startingResources;
    }

    /**
     * Gets count how many times can Building be in City
     *
     * @param name name of Building to get info about
     *
     * @return maximal allowed count of Building
     */
    public int getBuildingLimitsFromXML(String name) {

        if (name == null) {
            throw new IllegalArgumentException("Name cant be null");
        }
        int buildingLimit = 100;

        try {

            File fXmlFile = new File(locationString.getXMLLocation() + "\\limits.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = "/limits/buildingLimits/building[@id='" + name + "']";
            Node node = (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

            Element element = (Element) node;

            buildingLimit = Integer.parseInt(element.getElementsByTagName("limit").item(0).getTextContent());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return buildingLimit;
    }

    /**
     * Gets info what Buildings should be in newly created City from XML
     *
     * @return list of Buildings of new City
     */
    public List<BuildingInCity> getStartingBuildingsFromXML() {

        List<BuildingInCity> buildingInCity = new ArrayList<>();

        try {

            File fXmlFile = new File(locationString.getXMLLocation() + "\\limits.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression = "/limits/startingResources/buildings";
            Node node = (Node) xpath.evaluate(expression, doc, XPathConstants.NODE);

            Element element = (Element) node;

            for (int i = 0; i < element.getElementsByTagName("building").getLength(); i++) {
                Element e = (Element) element.getElementsByTagName("building").item(i);
                BuildingInCity b = new BuildingInCity();
                Coordinates c = new Coordinates();
                c.setX_coordinate(Integer.parseInt(e.getElementsByTagName("x").item(0).getTextContent()));
                c.setY_coordinate(Integer.parseInt(e.getElementsByTagName("y").item(0).getTextContent()));
                b.setCoordinates(c);
                b.setName(BuildingType.valueOf(e.getAttribute("id")));
                b.setLevel(Integer.parseInt(e.getElementsByTagName("level").item(0).getTextContent()));
                buildingInCity.add(b);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return buildingInCity;
    }
}
